// ViewManView.cpp : implementation file
//

#include "stdafx.h"
#include "ViewManView.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CViewManView

IMPLEMENT_DYNCREATE(CViewManView, CView)

CViewManView::CViewManView()
{
	m_nActiveView		= -1;  
	m_pNewView			=NULL;
	m_pActiveView		=NULL;
}

CViewManView::~CViewManView()
{
}


BEGIN_MESSAGE_MAP(CViewManView, CView)
	//{{AFX_MSG_MAP(CViewManView)
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CViewManView drawing

void CViewManView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CViewManView diagnostics

#ifdef _DEBUG
void CViewManView::AssertValid() const
{
	CView::AssertValid();
}

void CViewManView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CViewManView message handlers

BOOL CViewManView::CreateView(CRuntimeClass *pViewClass)
{
	CWnd* pWnd = NULL;

	CCreateContext context;		
	context.m_pNewViewClass		= pViewClass;
	context.m_pCurrentDoc		= GetDocument();
	context.m_pNewDocTemplate	= GetDocument()->GetDocTemplate();
	context.m_pLastView			= GetParentFrame()->GetActiveView();
	context.m_pCurrentFrame		= GetParentFrame();

	TRY
	{
		// Create the object.
		pWnd = DYNAMIC_DOWNCAST(CWnd, pViewClass->CreateObject());
		if (!pWnd) AfxThrowMemoryException();
	}
	CATCH_ALL(e)
	{
		TRACE0( "Out of memory creating a view.\n" );
		// Note: DELETE_EXCEPTION(e) not required
		return FALSE;
	}
	END_CATCH_ALL
		
	ASSERT_KINDOF(CWnd, pWnd);
	ASSERT(pWnd->m_hWnd == NULL); // not yet created.

	// Create with the right size and position
	if (!pWnd->Create(NULL, NULL, WS_CHILD|WS_BORDER,
		CRect(-800,-600,0,0), this, 0, &context))
	{
		TRACE0( "Warning: couldn't create client pane for view.\n" );
		// pWnd will be cleaned up by PostNcDestroy
		return FALSE;
	}
	pWnd->ShowWindow(SW_HIDE);
	pWnd->EnableWindow(FALSE);	
	// Set the newly create view as the active view.
	m_pNewView = DYNAMIC_DOWNCAST(CView, pWnd);
	ASSERT_KINDOF(CView, m_pNewView);	
	m_pNewView->OnInitialUpdate();
	
	return TRUE;
}

BOOL CViewManView::DeleteView(int nView)
{
	ASSERT_VALID( this );
	ASSERT(( nView >= 0 ) && (m_viewList.GetCount()>nView));
	TRACE2("***DeleteView: %d ( /%d )\n", nView,m_viewList.GetCount());
    // Now find the view we want to delete and remove it
    POSITION pos = m_viewList.FindIndex(nView);
    if( pos != NULL )
    {
		CView *pOldActiveView;
		pOldActiveView = m_pActiveView;
		// Ensure that we get no dangling pointers
		// DO NOT (RE-)MOVE THIS CODE ! Gero Kuehn [gero.kuehn@isc-soft.de]
		if(GetParentFrame()->GetActiveView() == DYNAMIC_DOWNCAST( CView, m_viewList.GetAt(pos)))
			GetParentFrame()->SetActiveView( NULL , FALSE);		
		// Remove item from list, and free memory.
		RemoveListItem(pos);
		return TRUE;
    }
	return FALSE;
}

CView* CViewManView::AddView(CRuntimeClass *pViewClass)
{
	if(CreateView(pViewClass))
	{
		m_viewList.AddTail(m_pNewView);
		return m_pNewView;
	}
	else
	{
		return NULL;
	}
}

void CViewManView::RemoveListItem(POSITION pos)
{
	if( pos != NULL )
	{
	    // remove the page from internal list
        CWnd *pWnd= m_viewList.GetAt(pos);
	    ASSERT(pWnd);
        // And delete the member window, freeing our stored
        // values relating to it
        if (pWnd != NULL) 
		{
            pWnd->DestroyWindow();
            pWnd = NULL;
        }
		// Remove from list and free memory.
	    m_viewList.RemoveAt(pos);		
    }
}

int CViewManView::GetViewCount()
{
	return m_viewList.GetCount();
}

BOOL CViewManView::SetActiveView(int nView)
{
	ASSERT_VALID(this);
	ASSERT(( nView >= 0 ) && ( m_viewList.GetCount() > nView ));	
	if(( nView != -1 ) /*&&(nView != m_nActiveView)*/)
	{
        POSITION pos = m_viewList.FindIndex( nView );
        if( pos != NULL )
		{
			// Hide the old view we are changing.
			// GK/ISC
			POSITION oldPos = NULL;
			if( m_nActiveView >= 0) 
			{
				oldPos = m_viewList.FindIndex( m_nActiveView );
			}

			if(oldPos)
			{
				CWnd* pWnd= m_viewList.GetAt( oldPos );
				pWnd->EnableWindow(FALSE);
				pWnd->ShowWindow(SW_HIDE);
			}

			// Show the newly selected view.
            CWnd* pWnd = m_viewList.GetAt( pos );
            pWnd->EnableWindow(TRUE);
            pWnd->ShowWindow(SW_SHOW);
			//pWnd->RedrawWindow();
            pWnd->SetFocus();
		    pWnd->SetActiveWindow();
		    // select the tab (if tab programmatically changed)
            m_nActiveView = nView;	    

            // Set the active view.
			m_pActiveView = DYNAMIC_DOWNCAST( CView, pWnd );
			ASSERT_KINDOF( CView, m_pActiveView );
		    GetParentFrame()->SetActiveView( m_pActiveView );
			CRect rc;
			GetClientRect(&rc);
			SendMessage(WM_SIZE,SIZE_MAXSHOW,MAKELPARAM(rc.Width(),rc.Height()));			
			return TRUE;
        }
		else
		{
			return FALSE;
		}
    }
	else
	{
		return FALSE;
	}
}

void CViewManView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	if(m_pActiveView && m_pActiveView->GetSafeHwnd())
	{
		::SetWindowPos(m_pActiveView->m_hWnd,HWND_TOP,0,0,cx,cy,SWP_SHOWWINDOW);
		//m_pActiveView->MoveWindow(0,0,cx,cy);
	}
}

CView* CViewManView::GetActiveView()
{
	return m_pActiveView;
}

BOOL CViewManView::PreCreateWindow(CREATESTRUCT& cs) 
{
	// TODO: Add your specialized code here and/or call the base class		
	return CView::PreCreateWindow(cs);
}
